/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.iec.edp.caf.rpc.api.channel;

import io.iec.edp.caf.commons.utils.SpringBeanUtils;
import io.iec.edp.caf.msu.api.client.ServiceDiscovery;
import lombok.var;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;

/**
 * 完整的rpc服务应包含服务注册、服务发现以及服务调用
 * caf的rpc框架服务注册及发现依托于caf的微服务架构
 */
public interface RpcChannel {

    /**
     * service register
     * 依托于msu的注册中心 默认无需额外注册
     */
    default void serviceRegister(){}

    /**
     * service discover
     * 依托于msu的注册中心 使用默认的服务发现方式
     * @param serviceUnit su Code
     * @return address
     */
    default String serviceDiscover(String serviceUnit){
        var serviceDiscovery = SpringBeanUtils.getBean(ServiceDiscovery.class);
        if(serviceDiscovery == null) return null;
        return serviceDiscovery.discover(serviceUnit, new HashMap<>());
    }

    /**
     * ordinary way to call remote service
     * @param version service version
     * @param serviceId service Id
     * @param parameters remote service parameters
     * @param context client to server context
     * @return
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IOException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
     String invokeRemoteService(String serviceId, String version, HashMap<String, String> parameters,
                              HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;

    /**
     * remote service to download stream
     * @param serviceId service Id
     * @param version service version
     * @param parameters service parameters
     * @param context client to server context
     * @return
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IOException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    InputStream invokeRemoteServiceStream(String serviceId, String version, HashMap<String, String> parameters,
                                         HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;

    /**
     * remote service to upload stream
     * @param inputStream file stream
     * @param serviceId service Id
     * @param version service version
     * @param parameters service parameters
     * @param context client to server context
     * @return
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IOException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    String invokeRemoteServiceStream(InputStream inputStream,String serviceId,String version,HashMap<String, String> parameters,
                                    HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;


//    /**
//     * ordinary way to call remote service
//     * @param type return type
//     * @param version service version
//     * @param serviceId service Id
//     * @param serviceUnitName MSU Code
//     * @param parameters remote service parameters
//     * @param cks cookies
//     * @param tenantId tenant Id
//     * @param context client to server context
//     * @param <T>
//     * @return
//     * @throws IllegalAccessException
//     * @throws ClassNotFoundException
//     * @throws InstantiationException
//     * @throws IOException
//     * @throws NoSuchMethodException
//     * @throws InvocationTargetException
//     */
//    <T> T invokeRemoteService(Type<T> type, String serviceId, String version, String serviceUnitName, HashMap<String, Object> parameters,
//                              Cookie[] cks, Integer tenantId, HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;
//
//    /**
//     * remote service to download stream
//     * @param serviceId service Id
//     * @param version service version
//     * @param serviceUnitName MSU code
//     * @param parameters service parameters
//     * @param cks cookies
//     * @param tenantId tenant Id
//     * @param context client to server context
//     * @return
//     * @throws IllegalAccessException
//     * @throws ClassNotFoundException
//     * @throws InstantiationException
//     * @throws IOException
//     * @throws NoSuchMethodException
//     * @throws InvocationTargetException
//     */
//    InputStream invokeRemoteServiceStream(String serviceId, String version, String serviceUnitName, HashMap<String, Object> parameters,
//                                          Cookie[] cks, Integer tenantId, HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;
//
//    /**
//     * remote service to upload stream
//     * @param inputStream file stream
//     * @param type return type
//     * @param serviceId service Id
//     * @param version service version
//     * @param serviceUnitName MSU Code
//     * @param parameters service parameters
//     * @param cks cookies
//     * @param tenantId tenant Id
//     * @param context client to server context
//     * @param <T>
//     * @return
//     * @throws IllegalAccessException
//     * @throws ClassNotFoundException
//     * @throws InstantiationException
//     * @throws IOException
//     * @throws NoSuchMethodException
//     * @throws InvocationTargetException
//     */
//    <T> T invokeRemoteServiceStream(InputStream inputStream,Type<T> type,String serviceId,String version, String serviceUnitName, HashMap<String, Object> parameters,
//                                    Cookie[] cks, Integer tenantId, HashMap<String, String> context) throws IllegalAccessException, ClassNotFoundException, InstantiationException, IOException, NoSuchMethodException, InvocationTargetException;

}
